import { Injectable, Logger, OnModuleInit, OnModuleDestroy } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { Cron, CronExpression } from '@nestjs/schedule';

/**
 * 安全监控服务
 * 零隐患MFIS规范 - 解决隐患：#4 熔断器监控
 */
@Injectable()
export class SecurityMonitorService implements OnModuleInit, OnModuleDestroy {
  private readonly logger = new Logger(SecurityMonitorService.name);
  private monitoringInterval: NodeJS.Timeout;
  private alertThresholds = {
    memoryUsage: 0.8, // 80%
    cpuUsage: 0.7,    // 70%
    errorRate: 0.1,   // 10%
    responseTime: 5000, // 5秒
  };

  private metrics = {
    requests: 0,
    errors: 0,
    responseTime: [],
    lastReset: Date.now(),
  };

  constructor(private readonly configService: ConfigService) {}

  async onModuleInit() {
    this.logger.log('安全监控服务已启动');
  }

  async onModuleDestroy() {
    await this.stop();
  }

  async start(): Promise<void> {
    // 每分钟执行安全检查
    this.monitoringInterval = setInterval(() => {
      this.performSecurityCheck();
    }, 60000);
  }

  async stop(): Promise<void> {
    if (this.monitoringInterval) {
      clearInterval(this.monitoringInterval);
      this.monitoringInterval = null;
    }
    this.logger.log('安全监控服务已停止');
  }

  /**
   * 每小时重置指标
   */
  @Cron(CronExpression.EVERY_HOUR)
  resetMetrics(): void {
    this.metrics = {
      requests: 0,
      errors: 0,
      responseTime: [],
      lastReset: Date.now(),
    };

    this.logger.debug('安全指标已重置');
  }

  /**
   * 记录请求指标
   */
  recordRequest(responseTime: number, isError: boolean = false): void {
    this.metrics.requests++;
    if (isError) {
      this.metrics.errors++;
    }
    this.metrics.responseTime.push(responseTime);

    // 保留最近1000个响应时间
    if (this.metrics.responseTime.length > 1000) {
      this.metrics.responseTime = this.metrics.responseTime.slice(-1000);
    }
  }

  /**
   * 执行安全检查
   */
  private async performSecurityCheck(): Promise<void> {
    try {
      const memoryUsage = this.getMemoryUsage();
      const errorRate = this.getErrorRate();
      const avgResponseTime = this.getAverageResponseTime();

      // 检查内存使用率
      if (memoryUsage > this.alertThresholds.memoryUsage) {
        this.logger.warn('内存使用率过高', {
          usage: `${(memoryUsage * 100).toFixed(2)}%`,
          threshold: `${(this.alertThresholds.memoryUsage * 100).toFixed(2)}%`,
        });
      }

      // 检查错误率
      if (errorRate > this.alertThresholds.errorRate) {
        this.logger.warn('错误率过高', {
          errorRate: `${(errorRate * 100).toFixed(2)}%`,
          errors: this.metrics.errors,
          requests: this.metrics.requests,
        });
      }

      // 检查响应时间
      if (avgResponseTime > this.alertThresholds.responseTime) {
        this.logger.warn('平均响应时间过长', {
          avgResponseTime: `${avgResponseTime}ms`,
          threshold: `${this.alertThresholds.responseTime}ms`,
        });
      }

      // 记录系统状态
      this.logger.debug('系统安全检查完成', {
        memoryUsage: `${(memoryUsage * 100).toFixed(2)}%`,
        errorRate: `${(errorRate * 100).toFixed(2)}%`,
        avgResponseTime: `${avgResponseTime}ms`,
        uptime: `${Math.round(process.uptime())}s`,
      });

    } catch (error) {
      this.logger.error('安全检查失败', {
        error: error.message,
      });
    }
  }

  /**
   * 获取内存使用率
   */
  private getMemoryUsage(): number {
    const memUsage = process.memoryUsage();
    const totalMemory = require('os').totalmem();
    return memUsage.rss / totalMemory;
  }

  /**
   * 获取错误率
   */
  private getErrorRate(): number {
    if (this.metrics.requests === 0) return 0;
    return this.metrics.errors / this.metrics.requests;
  }

  /**
   * 获取平均响应时间
   */
  private getAverageResponseTime(): number {
    if (this.metrics.responseTime.length === 0) return 0;
    const sum = this.metrics.responseTime.reduce((a, b) => a + b, 0);
    return sum / this.metrics.responseTime.length;
  }

  /**
   * 获取安全状态
   */
  getSecurityStatus(): any {
    return {
      status: 'healthy',
      metrics: {
        requests: this.metrics.requests,
        errors: this.metrics.errors,
        error_rate: this.getErrorRate(),
        avg_response_time: this.getAverageResponseTime(),
        memory_usage: this.getMemoryUsage(),
      },
      thresholds: this.alertThresholds,
      uptime: process.uptime(),
      timestamp: new Date().toISOString(),
    };
  }
}